// axios 封装
import Axios, { AxiosError, AxiosResponse, AxiosInstance, AxiosRequestConfig, InternalAxiosRequestConfig } from 'axios';
import eventEmitter from '@/utils/eventEmitter';
import { getMessageInfo } from './status';
import { useMessage } from '@/hooks/useMessage';
import cancel from './cancel';

const isMock = Boolean(import.meta.env.VITE_APP_USE_MOCK); // 判断是否使用 mock

const defaultConfig: AxiosRequestConfig = {
  baseURL: isMock ? import.meta.env.VITE_APP_MOCK_BASEURL : import.meta.env.VITE_APP_API_BASEURL, // 基础url,
  timeout: 5000, // 超时时间
  headers: {
    'Accept': 'application/json, text/plain, */*',
    'Content-Type': 'application/json',
    'X-Requested-With': 'XMLHttpRequest'
  }
};

class HttpRequest {
  private static axiosInstance: AxiosInstance = Axios.create(defaultConfig); // 保存当前Axios实例对象
  constructor() {
    // 初始化拦截器
    this.setInterceptorsRequest();
    this.setInterceptorsResponse();
  }
  // 请求拦截
  private setInterceptorsRequest() {
    const instance = HttpRequest.axiosInstance;
    instance.interceptors.request.use(
      (config: InternalAxiosRequestConfig) => {
        const token = 'token';
        if (token) config.headers['Authorization'] = 'Bearer ' + token;
        cancel.pendingHandler(config); // 取消请求逻辑处理
        eventEmitter.on('ROUTER:CANCEL_PENDING', () => {
          // 用于路由切换取消所有请求
          cancel.cancelAllPending();
        });
        return config;
      },
      (error: AxiosError) => {
        return Promise.reject(error);
      }
    );
  }

  // 响应拦截
  private setInterceptorsResponse() {
    const instance = HttpRequest.axiosInstance;
    instance.interceptors.response.use(
      (response: AxiosResponse) => {
        const { data, config } = response;
        cancel.removePending(config);
        if (data.code === 200) return data;
        // 处理错误
        useMessage('error', getMessageInfo(data.code));
        switch (data.code) {
          case 401:
            // 未登录
            eventEmitter.emit('API:UN_AUTH');
            break;
          case 402:
            // 无效
            eventEmitter.emit('API:INVALID');
            break;
          case 403:
            // 禁止
            eventEmitter.emit('API:FORBIDDEN');
            break;
          default:
            return Promise.reject(response);
        }
      },
      (error: AxiosError) => {
        const { response, code } = error;
        const isCancel: boolean = code === 'ERR_CANCELED';
        if (!isCancel) useMessage('error', getMessageInfo(response?.status));
        return Promise.reject(error);
      }
    );
  }

  // 通用请求函数
  request<T>(config: AxiosRequestConfig): Promise<T> {
    return new Promise((resolve, reject) => {
      HttpRequest.axiosInstance
        .request(config)
        .then(response => resolve(response as T))
        .catch(error => reject(error));
    });
  }
  get<T, U>(url: string, params?: T, config?: AxiosRequestConfig): Promise<U> {
    return this.request({
      ...config,
      url,
      params,
      method: 'GET'
    });
  }
  post<T, U>(url: string, data?: T, config?: AxiosRequestConfig): Promise<U> {
    return this.request({
      ...config,
      url,
      data,
      method: 'POST'
    });
  }
}

export default new HttpRequest();
